//
//  PhotoScrollView.m
//  PrintFamily
//
//  Created by edaihua on 16/3/5.
//  Copyright © 2016年 ___PrintFactory___. All rights reserved.
//

#import "PhotoScrollView.h"
#import "PFPhoto.h"
#import "PFPhotoRectManager.h"

@interface PhotoScrollView() <UIScrollViewDelegate, UIGestureRecognizerDelegate>

@property (strong, nonatomic) __block UIImageView *photoView;

@property (nonatomic) CGSize imageSize;

@property CGPoint pointToCenterAfterResize;
@property CGFloat scaleToRestoreAfterResize;

@property (nonatomic) CGFloat maxContentOffsetX; // The absolute value of offset range, example, 20 means range (-20, 20)
@property (nonatomic) CGFloat minContentOffsetX;
@property (nonatomic) CGFloat maxContentOffsetY;
@property (nonatomic) CGFloat minContentOffsetY;

@property (nonatomic) CGPoint contentOffsetAfterZoom;

@property (nonatomic) CGPoint targetOriginInPhotoView;

@end

@import Photos;

@implementation PhotoScrollView

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.showsHorizontalScrollIndicator = NO;
        self.showsVerticalScrollIndicator = NO;
        self.backgroundColor = [UIColor clearColor];
        self.bouncesZoom = YES;
        self.bounces = YES;
        self.decelerationRate = UIScrollViewDecelerationRateNormal;
        self.delegate = self;
        self.backgroundColor = [UIColor blackColor];
        self.targetOriginInPhotoView = CGPointZero;
        self.contentOffsetAfterZoom = CGPointZero;
        CGSize screenSize = [AppDelegate getScreenSize];
        
        //self.contentSize = CGSizeMake(screenSize.width * 3, screenSize.height * 3);
        self.contentInset = UIEdgeInsetsMake(screenSize.height, screenSize.width, screenSize.height, screenSize.width);

        [self.panGestureRecognizer addTarget:self action:@selector(handlePanGesture:)];
        self.panGestureRecognizer.delegate = self;
        
        UITapGestureRecognizer* doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTapGesture:)];
        [doubleTapGestureRecognizer setNumberOfTapsRequired:2];
        [self addGestureRecognizer:doubleTapGestureRecognizer];
        
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
}

- (void)displayPhotoWithAsset:(PHAsset*)asset {
    
    self.zoomScale = self.photo.rectManager.zoomScale;
    
    void (^resultHandler)(UIImage*, NSDictionary*) = ^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
        if (!result) {
            return;
        }
        
        if (self.photoView) {
            [self.photoView removeFromSuperview];
        }
        
        UIImage *resultImage = result;
        
        BOOL isLandscape = result.size.width > result.size.height;
        if (isLandscape) {
            resultImage = [UIImage imageWithCGImage:result.CGImage scale:result.scale orientation:UIImageOrientationRight];
        }
        
        PFPhotoRectManager *photoRectManager = self.photo.rectManager;
        self.photoView = [[UIImageView alloc] initWithFrame:[photoRectManager getImageRectWithoutScale]];
        self.photoView.contentMode = UIViewContentModeScaleAspectFit;
        [self addSubview:self.photoView];
        [self bringSubviewToFront:self.photoView];
        
        [self.photoView setImage:resultImage];
        [self configureForImageSize:resultImage.size];
        
        self.contentOffset = photoRectManager.contentOffset;
        [self setZoomScale:photoRectManager.zoomScale animated:YES];
        self.contentOffsetAfterZoom = photoRectManager.contentZoomOffset;
        
        [self calculateMaxMinOffsetWithPhotoSize:CGSizeMake(self.photoView.frame.size.width * self.zoomScale, self.photoView.frame.size.height * self.zoomScale)];
    };
    
    PHImageRequestOptions* requestOption = [[PHImageRequestOptions alloc] init];
    requestOption.synchronous = NO;
    requestOption.resizeMode = PHImageRequestOptionsResizeModeFast;
    requestOption.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;
    requestOption.networkAccessAllowed = NO;
    
    [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:requestOption resultHandler:resultHandler];
}

- (void)configureForImageSize:(CGSize)imageSize  {
    
    self.imageSize = imageSize;
    [self setMaxMinZoomScales];
    
}

- (void)setMaxMinZoomScales {
    CGSize screenSize = [AppDelegate getScreenSize];
    CGRect targetRect = [self.photo.rectManager.commonRectManager getTargetPhotoRectInResizeView];
    
    if (self.photo.rectManager.isShorterThanTarget) {
        CGFloat scale = self.imageSize.height / targetRect.size.height;
        CGFloat scaledImageWidth = self.imageSize.width / scale;
        self.minimumZoomScale = targetRect.size.width / scaledImageWidth;
    } else {
        CGFloat scale = self.imageSize.width / targetRect.size.width;
        CGFloat scaledImageHeight = self.imageSize.height / scale;
        self.minimumZoomScale = targetRect.size.height / scaledImageHeight;
    }
    
    self.maximumZoomScale = (screenSize.width - 20) / targetRect.size.width;
    
    if (self.minimumZoomScale > self.maximumZoomScale) {
        self.minimumZoomScale = self.maximumZoomScale;
    }
}

- (void)calculateMaxMinOffsetWithPhotoSize:(CGSize)photoSize {
    
    CGSize targetPhotoSize = self.photo.rectManager.commonRectManager.targetPhotoSize;
    CGFloat absOffsetX = fabs((photoSize.width - targetPhotoSize.width) / 2);
    CGFloat absOffsetY = fabs((photoSize.height - targetPhotoSize.height) / 2);
    
    self.maxContentOffsetX = self.contentOffsetAfterZoom.x + absOffsetX;
    self.minContentOffsetX = self.contentOffsetAfterZoom.x - absOffsetX;
    self.maxContentOffsetY = self.contentOffsetAfterZoom.y + absOffsetY;
    self.minContentOffsetY = self.contentOffsetAfterZoom.y - absOffsetY;
}

- (void)updateContentOffsetAfterZoom {
    CGRect imageRectWithoutScale = [self.photo.rectManager getImageRectWithoutScale];
    
    CGFloat offsetX = (self.zoomScale - 1) * imageRectWithoutScale.size.width * 0.5;
    CGFloat offsetY = (self.zoomScale - 1) * imageRectWithoutScale.size.height * 0.5;
    self.contentOffsetAfterZoom = CGPointMake(offsetX, offsetY);
}

#pragma mark - <UIScrollViewDelegate>
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
    
}

- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return self.photoView;
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
    
    [self updateContentOffsetAfterZoom];
    [self setContentOffset:self.contentOffsetAfterZoom animated:YES];
    
    [self calculateMaxMinOffsetWithPhotoSize:self.photoView.frame.size];
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    
}

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView {
    
}

- (BOOL)touchesShouldBegin:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    
    return NO;
}


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    
    return YES;
}

#pragma mark - gesture handling
- (void)handleDoubleTapGesture:(UITapGestureRecognizer*)recognizer {
    self.zoomScale = 1.0;
    
    [self updateContentOffsetAfterZoom];
    [self calculateMaxMinOffsetWithPhotoSize:self.photoView.frame.size];
    [self setContentOffset:CGPointZero animated:YES];
}

- (void)handlePanGesture:(UIPanGestureRecognizer*)recognizer {
    
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        CGPoint adjustedContentOffset = self.contentOffset;
        
        if ((self.contentOffset.x) > self.maxContentOffsetX) {
            adjustedContentOffset.x = self.maxContentOffsetX;
        } else if ((self.contentOffset.x) < self.minContentOffsetX) {
            adjustedContentOffset.x = self.minContentOffsetX;
        }
        
        if ((self.contentOffset.y) > self.maxContentOffsetY) {
            adjustedContentOffset.y = self.maxContentOffsetY;
        } else if ((self.contentOffset.y) < self.minContentOffsetY) {
            adjustedContentOffset.y = self.minContentOffsetY;
        }
        
        [self setContentOffset:adjustedContentOffset animated:YES];
    }
}

- (CGRect)getCropPixelRect {
    PFPhotoRectManager* rectManager = self.photo.rectManager;
    CGSize targetPhotoSize       = rectManager.commonRectManager.targetPhotoSize;
    //CGRect targetRect            = [rectManager.commonRectManager getTargetPhotoRectInResizeView];
    CGRect imageRectWithoutScale = [rectManager getImageRectWithoutScale];
    CGSize imageSize             = self.contentSize;
    CGSize imagePixelSize        = rectManager.imagePixelSize;
    CGFloat imageScale           = imagePixelSize.width / imageSize.width;
    CGPoint cropPixelOrigin      = CGPointZero;
    CGSize  cropPixelSize        = CGSizeZero;
    
    if ([rectManager isShorterThanTargetHeight]) {
        if (self.contentSize.height < targetPhotoSize.height) {
            cropPixelOrigin = CGPointMake(((imageRectWithoutScale.size.width - targetPhotoSize.width) * 0.5 + self.contentOffset.x) * imageScale, 0);
            cropPixelSize   = CGSizeMake(targetPhotoSize.width * imageScale, imageSize.height * imageScale);
        } else {
            cropPixelOrigin = CGPointMake(((imageRectWithoutScale.size.width  - targetPhotoSize.width) * 0.5 + self.contentOffset.x) * imageScale,  ((imageRectWithoutScale.size.height - targetPhotoSize.height) * 0.5 + self.contentOffset.y) * imageScale);
            cropPixelSize = CGSizeMake(targetPhotoSize.width * imageScale, targetPhotoSize.height * imageScale);
        }
    } else {
        if (self.contentSize.width < targetPhotoSize.width) {
            cropPixelOrigin = CGPointMake(0, ((imageRectWithoutScale.size.height - targetPhotoSize.height) * 0.5 + self.contentOffset.y) * imageScale);
            cropPixelSize   = CGSizeMake(imageSize.width * imageScale, targetPhotoSize.height * imageScale);
        } else {
            cropPixelOrigin = CGPointMake(((imageRectWithoutScale.size.width  - targetPhotoSize.width) * 0.5 + self.contentOffset.x) * imageScale,  ((imageRectWithoutScale.size.height - targetPhotoSize.height) * 0.5 + self.contentOffset.y) * imageScale);
            cropPixelSize = CGSizeMake(targetPhotoSize.width * imageScale, targetPhotoSize.height * imageScale);
        }
    }

    return CGRectMake(cropPixelOrigin.x, cropPixelOrigin.y, cropPixelSize.width, cropPixelSize.height);
}

- (void)savePhotoResizeStatus {
    
    if (self.isZooming == NO) {

        PFPhotoRectManager *rectManager = self.photo.rectManager;
        rectManager.contentZoomOffset   = self.contentOffsetAfterZoom;
        rectManager.cropPixelRect       = [self getCropPixelRect];
        rectManager.zoomScale           = self.zoomScale;
        rectManager.contentOffset       = self.contentOffset;
    }
}


@end
